package com.recipedb.sprint.service.impl;

import org.springframework.transaction.annotation.Transactional;
import com.recipedb.sprint.entity.Sessions;
import com.recipedb.sprint.entity.Users;
import com.recipedb.sprint.repository.PointRecordsRepository;
import com.recipedb.sprint.repository.PointsRewardsRepository;
import com.recipedb.sprint.repository.SessionsRepository;
import com.recipedb.sprint.repository.UsersRepository;
import com.recipedb.sprint.service.AdminService;
import com.recipedb.sprint.security.JwtUtil;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class AdminServiceImpl implements AdminService {

    private final UsersRepository usersRepository;
    private final SessionsRepository sessionsRepository;
    private final BCryptPasswordEncoder passwordEncoder;
    private final PointsRewardsRepository pointsRewardsRepository; // 新增
    private final PointRecordsRepository pointRecordsRepository; // 新

    public AdminServiceImpl(UsersRepository usersRepository,
                            SessionsRepository sessionsRepository,
                            PointsRewardsRepository pointsRewardsRepository,
                            PointRecordsRepository pointRecordsRepository,
                            BCryptPasswordEncoder passwordEncoder) {
        this.usersRepository = usersRepository;
        this.sessionsRepository = sessionsRepository;
        this.passwordEncoder = passwordEncoder;
        this.pointsRewardsRepository = pointsRewardsRepository;
        this.pointRecordsRepository = pointRecordsRepository;
    }

    // 管理员登录（固定管理员：userid=0）
    @Override
    public Map<String, Object> adminLogin(String account, String password) {
        Users admin = usersRepository.findByUsername(account)
                .orElseThrow(() -> new RuntimeException("管理员账号不存在"));

        if (admin.getUserid() != 0L) {
            throw new RuntimeException("该账号无管理员权限");
        }

        if (!passwordEncoder.matches(password, admin.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        String token = JwtUtil.generateToken(admin.getUsername());
        Map<String, Object> data = new HashMap<>();
        data.put("adminId", admin.getUserid());
        data.put("username", admin.getUsername());
        data.put("token", token);
        return data;
    }

    // 查询单个用户
    @Override
    public Users getUserById(Long userId) {
        return usersRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在（userid=" + userId + "）"));
    }


    // 查询所有用户
    @Override
    public List<Users> getAllUsers(String keyword) {
        if (keyword == null || keyword.isEmpty()) {
            return usersRepository.findAll();
        } else {
            List<Users> phoneMatch = usersRepository.findByPhone(keyword)
                    .map(Collections::singletonList)
                    .orElse(Collections.emptyList());
            List<Users> usernameMatch = usersRepository.findByUsername(keyword)
                    .map(Collections::singletonList)
                    .orElse(Collections.emptyList());

            return Stream.concat(phoneMatch.stream(), usernameMatch.stream())
                    .distinct()
                    .collect(Collectors.toList());
        }
    }

    // 新增用户
    @Override
    public void createUser(Users user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        usersRepository.save(user);
    }

    // ：编辑用户
    @Override
    public void updateUser(Long userId, Users user) {
        Users existingUser = usersRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        existingUser.setUsername(user.getUsername());
        if (!Objects.equals(existingUser.getPhone(), user.getPhone())) {
            if (usersRepository.existsByPhoneAndUseridNot(user.getPhone(), userId)) {
                throw new RuntimeException("手机号已被使用");
            }
            existingUser.setPhone(user.getPhone());
        }
        existingUser.setUpdatedAt(LocalDateTime.now());
        usersRepository.save(existingUser);
    }

    // 删除用户
    @Override
    @Transactional
    public void deleteUser(Long userId) {
        if (!usersRepository.existsById(userId)) {
            throw new RuntimeException("用户不存在");
        }
        //删除用户的所有会话记录
        List<Sessions> userSessions = sessionsRepository.findByUserid(userId); // 需在SessionsRepository中定义该方法
        if (!userSessions.isEmpty()) {
            sessionsRepository.deleteAll(userSessions);
        }

        // 删除用户的积分变动记录（point_records）
        pointRecordsRepository.deleteByUserid(userId); // 需在Repository中定义该方法

        // 删除用户的积分记录（points_rewards）
        pointsRewardsRepository.deleteById(userId); // 因points_rewards主键是userid

        usersRepository.deleteById(userId);
    }

    // 数据统计看板
    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalUsers", usersRepository.count());
        stats.put("todayNewUsers", usersRepository.countByCreatedAtAfter(LocalDateTime.now().minusDays(1)));
        stats.put("totalSessions", sessionsRepository.count());
        return stats;
    }


    /**
     * 实现：查询指定用户的所有会话（按创建时间倒序）
     */
    @Override
    public List<Sessions> getUserSessions(Long userId) {
        // 校验用户存在（避免查询不存在的用户会话）
        if (!usersRepository.existsById(userId)) {
            throw new RuntimeException("用户不存在（userid=" + userId + "）");
        }
        // 调用 Repository 查询（需在 SessionsRepository 中定义该方法）
        return sessionsRepository.findByUseridOrderByCreatedAtDesc(userId);
    }

    /**
     * 实现：查询所有会话（全局查看，按创建时间倒序）
     */
    @Override
    public List<Sessions> getAllSessions() {
        return sessionsRepository.findAllByOrderByCreatedAtDesc();
    }

    /**
     * 实现：删除单个 Session
     */
    @Override
    @Transactional
    public void deleteSession(Long sessionId) {
        // 校验 Session 是否存在
        if (!sessionsRepository.existsById(sessionId)) {
            throw new RuntimeException("Session不存在（sessionId=" + sessionId + "）");
        }
        sessionsRepository.deleteById(sessionId);
    }

}
